/*
 MIT License
 
 Copyright (c) 2021 Steven Le

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:
 
 The above copyright notice and this permission notice shall be included in all
 copies or substantial portions of the Software.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
*/

/**
 *	lx_who1.c 
 * 		- version0.3 of my who program
 *		open, read UTMP file, and show results
 * 		- supresses empty records
 *		- formats time nicely
 * 		- buffers input (using utmplib) 	 
 */
#include<stdio.h>
#include<sys/types.h>
#include<utmp.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<time.h>
#include"utmplib.c"

/* #define SHOWHOST */
#define SHOWHOST			/* include remote machine on output */


void show_info(struct utmp *utbufp);
void show_time(time_t);

int main() {
	
	struct utmp * utbufp, 		/* holds pointer to next rec */
		    * utmp_next();	/* returns pointer to next */

	if (utmp_open(UTMP_FILE) == -1) {
		perror(UTMP_FILE);
		exit(1);
	}

	while ((utbufp = utmp_next()) != ((struct utmp*) NULL))
		show_info(utbufp); 
	utmp_close();

	return 0;			/* went ok */
}

/**
 *	show_info()	
 * 	-	displays contents of the utmp struct in 
 * 		human readable form
 * 	-	displays nothings if recored has no user name
 */ 

void show_info(struct utmp *utbufp)
{
	if (utbufp->ut_type != USER_PROCESS)
		return;

	printf("%-8.8s", utbufp->ut_name); 		/* the logname  */
	printf(" "); 					/* a space */
	printf("%-8.8s", utbufp->ut_line); 		/* the tty  */
	printf(" "); 					/* a space */
	show_time(utbufp->ut_time); 			/* login time */
	printf(" "); 					/* a space */
#ifdef SHOWHOST
	printf("%-8.8s", utbufp->ut_host); 		/* the host  */
#endif
	printf("\n"); 					/* newline */
}

/*
 *	show_time
 * 	- 	display time in a format fit for human comsumption
 *		uses ctime to build a string then picks parts out of 
 * 		it, Notes: %12.12s prints a string 12 chars wide and 
 * 		LIMITS it to 12chars.
 */
void show_time(long timeval)
{
	char *cp; 			/* to hold address of time  */
	cp = ctime(&timeval); 		/* convert time to string */
					/* string looks like */
					/* Mon Feb 4 00:46:40 EST 1991*/
					/* 0123456789012345 */
	printf("12.12 %s", cp + 4); 	/* pick 12 chars from pos 4 */
}
